import type {Effect, ImmerReducer} from 'umi';
import {addDictNode, findChildData, updateDictNode} from "@/services/dict/api";

export const dictModelName = 'dictModel'

export interface DictItem {
  createTime: Date;
  dictCode: string;
  hasChildren: boolean;
  id: string;
  isDeleted: number;
  isLeaf: boolean;
  key: number;
  leaf: boolean;
  name: string;
  param: Record<string, any>;
  parentId: string;
  title: string;
  updateTime: Date;
  value: string;
  children?: DictItem[];
};

export interface DictModelState {
  dictTreeData: DictItem[];
}

export enum DictEffectKeys {
  Query = "query",
  AppendChild = "appendChild",
  UpdateNode = "updateNode",
  AddNode = "addNode",
}

export interface DictModelType {
  namespace: 'dictModel';
  state: DictModelState;
  effects: {
    [DictEffectKeys.Query]: Effect;
    [DictEffectKeys.AppendChild]: Effect;
    [DictEffectKeys.UpdateNode]: Effect;
    [DictEffectKeys.AddNode]: Effect;
  },
  reducers: {
    saveDictTreeData: ImmerReducer<DictModelState>,
    appendChildReducers: ImmerReducer<DictModelState>,
    updateNodeReducer: ImmerReducer<DictModelState>,
  }
}

const DictModel: DictModelType = {
  namespace: dictModelName,
  state: {
    dictTreeData: []
  },
  effects: {
    * [DictEffectKeys.Query]({payload}, {call, put}) {
      console.log(payload)
      const response = yield call(findChildData, payload)
      const {data} = response;
      yield put({
        type: 'saveDictTreeData',
        payload: data,
      });
    },
    * [DictEffectKeys.AppendChild]({payload}, {call, put}) {
      console.log(payload)
      const response = yield call(findChildData, payload)
      const {data} = response;
      yield put({
        type: 'appendChildReducers',
        payload: {
          id: payload,
          data
        },
      });
    },
    * [DictEffectKeys.UpdateNode]({payload}, {call, put}) {
      yield call(updateDictNode, payload)
      yield put({
        type: 'updateNodeReducer',
        payload
      })
    },
    * [DictEffectKeys.AddNode]({payload}, {call, put}) {
      yield call(addDictNode, payload)
      yield put({
        type: 'appendChildReducers',
        payload: {
          id: payload.parentId,
          data: payload
        }
      })
    }
  },
  reducers: {
    saveDictTreeData(state, action) {
      state.dictTreeData = action.payload
    },
    appendChildReducers(state, action) {
      const {payload} = action

      function appendChild(dictTreeData: DictItem[]) {
        dictTreeData.forEach(data => {
          if (data.id === payload.id) {
            if (Array.isArray(data.children)) {
              if (Array.isArray(payload.data)) {
                // 两个都是数组
                data.children = data.children.concat(payload.data)
              } else {
                data.children.push(payload.data)
              }
            } else {
              // 不是数组直接=
              data.children = payload.data
            }


          }
          if (data.children) {
            appendChild(data.children)
          }
        })
      }

      appendChild(state.dictTreeData)
    },
    updateNodeReducer(state, action) {
      const {payload} = action

      // 递归找到节点,更新
      function updateNode(dictTreeData: DictItem[]) {
        dictTreeData.forEach(data => {
          if (data.id === payload.id) {
            data.name = payload.name;
            data.value = payload.value;
            data.dictCode = payload.dictCode
            console.log(data)
          }
          if (data.children) {
            updateNode(data.children)
          }
        })
      }

      updateNode(state.dictTreeData)
    }
  }
}

export default DictModel;
